package resources;

import java.sql.Connection;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.log4j.Logger;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

import utilities.ConfigurationProperties;
import utilities.Costanti;
import connectors.DBManager;

/*
 * Risorsa REST per permettere ai client di effettuare una visura ACI PRA
 */

//RISORSA ANCORA DA FINIRE!

@Path("/visuraACI")
public class VisuraACIResource {
	
		static Logger logger = Logger.getLogger(VisuraACIResource.class);
		
		public static String ACI_PRA_REST_URL = ConfigurationProperties.getString("indirizzoIP_ACIPRA");		
		
	    public static String getDateCurrent(GregorianCalendar current){
	        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
	        String data =  format.format(current.getTime());
	         return data;
	     }
	    	
		/**
		 * @param datiRicevuti
		 * @return
		 */
		@POST
		@Produces(MediaType.APPLICATION_JSON)
		@Consumes(MediaType.APPLICATION_JSON)
		public JSONObject nuovaVisuraAciPra(JSONObject datiRicevuti){
			
			logger.info("Nuova richiesta di visura ricevuta");
			// 
			//codice per il calcolo tempo esecuzione
			//			
			long inizio = System.currentTimeMillis();
			long fine = 0;
			long inizioDB = 0;
			long fineDB = 0;
			long inizioACI = 0;
			long fineACI = 0;
			
	      	JSONObject jsonToReturn = new JSONObject();
	      	boolean errore = false;
	      	String esito = "";
	      	String targa = "";
	      	DBManager dBmanager = null;
	      	Connection con = null;
			String matricola = "";
			String codice_agente = "";
			String imei = "";
	      	
	      	//inizializzo i campi dell'oggetto JSON di risposta
	      	try{
				jsonToReturn.put("esito_operazione", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
				jsonToReturn.put("codice_errore","");
				jsonToReturn.put("info","");
				jsonToReturn.put("esito_visura","");
				jsonToReturn.put("denominazione","");
				jsonToReturn.put("comune_nascita","");
				jsonToReturn.put("provincia_nascita","");
				jsonToReturn.put("data_nascita","");
				jsonToReturn.put("residenza","");
				jsonToReturn.put("provincia_residenza","");
				jsonToReturn.put("tsFE",-1);
				jsonToReturn.put("tsBE",-1);
				jsonToReturn.put("tsACI",-1);

	      		
	      	}catch(JSONException je){}
	      	
	      	//Imposto parametri per richiedere visura (per ora sono statici)
	      	String userID = ConfigurationProperties.getString("userID");
			String password = ConfigurationProperties.getString("password");
			String tipoveic= "1";          //1 - Autoveicolo, 2 - Rimorchio, 4 - Motociclo
			String tipoRichiesta = "T";    //T - targa, L - telaio
		    GregorianCalendar dataAttuale =  new GregorianCalendar();
		    String datarif = getDateCurrent(dataAttuale);
		    
		    //parsing dei dati ricevuti
			try{
				targa = datiRicevuti.getString("targa");
				matricola = datiRicevuti.getString("matricola_agente");
				codice_agente = datiRicevuti.getString("codice_agente");
				imei = datiRicevuti.getString("IMEI");
				
			}catch(JSONException e) {
				errore = true;
				try{
			      	jsonToReturn.put("codice_errore",Costanti.PARSING_DATA_ERROR);
			      	jsonToReturn.put("info","Errore nell'elaborazione dell'oggetto JSON ricevuto: "+e.getMessage());
				}catch(JSONException je){}
				
				logger.error("Errore nella elaborazione dell'oggetto JSON ricevuto: "+e.getMessage());
			}
			if(!errore){
				//Verifica attraverso il DB le credenziali dell'utente
				dBmanager = DBManager.getDBManager();
				if((con = dBmanager.connect())!=null){
					try{
						inizioDB = System.currentTimeMillis();//codice per il calcolo ts
						esito = dBmanager.login(con,matricola,codice_agente,imei);
						fineDB = System.currentTimeMillis();//codice per il calcolo ts
					}
					catch(SQLException se) {
						errore = true;
						try{
					      	jsonToReturn.put("codice_errore",Costanti.SQL_ERROR);
					      	jsonToReturn.put("info","Errore nell'esecuzione della query SQL: "+se.getMessage());
						}catch(JSONException je){}
						
						logger.error("Errore nell'esecuzione della query SQL: "+se.getMessage());
					}
					catch(Exception ex){
						errore = true;
						try{
					      	jsonToReturn.put("codice_errore",Costanti.GENERIC_ERROR);
					      	jsonToReturn.put("info","Errore: "+ex.getMessage());
						}catch(JSONException je){}
						
						logger.error("Errore: "+ex.getMessage());
						
					}finally{
						if(dBmanager != null)	dBmanager.disconnect(con);
					}
				}
				else{
					errore = true;
					try{
				      	jsonToReturn.put("codice_errore",Costanti.DB_CONNECTION_ERROR);
				      	jsonToReturn.put("info","Errore nella connessione al DB server");
					}catch(JSONException je){}
			      	
			      	logger.error("Errore nella connessione al DB");
				}
				
				//fallimento nell'autenticazione del dispositivo o nell'agente
				if(!esito.equals("Successo") && !errore){
					errore = true;
					try{
				      	jsonToReturn.put("esito_operazione", HttpServletResponse.SC_UNAUTHORIZED);
				      	if(esito.equals("Dispositivo non autorizzato"))    		 jsonToReturn.put("codice_errore",Costanti.UNKNOWN_DEVICE);
				      	else jsonToReturn.put("codice_errore",Costanti.UNKNOWN_AGENT);
				      	jsonToReturn.put("info","Errore: "+esito);
					}catch(JSONException je){}
					
					logger.info("Operazione non valida: "+esito);			
				}
				//l'agente è stato correttamente autenticato quindi posso fare la visura
				if(esito.equals("Successo") && !errore ){
					//creo un client per connettermi al web service ACIPRARest
				    ClientConfig cc = new DefaultClientConfig();
				    Client c = Client.create(cc);			    
				    JSONObject toSend = new JSONObject();
				    try{
				    	logger.info("Sto per interrogare ACIPRARest");	    	
						toSend.put("userID",userID);
						toSend.put("password",password);
						toSend.put("targa",targa);
						toSend.put("tipoVeicolo",tipoveic);
						toSend.put("tipoRichiesta",tipoRichiesta);
						toSend.put("dataRiferimento",datarif);
											
						
						inizioACI = System.currentTimeMillis();//per calcolo ts
						WebResource r = c.resource(ACI_PRA_REST_URL);
					    JSONObject resp = r.accept(MediaType.APPLICATION_JSON_TYPE). entity(toSend, MediaType.APPLICATION_JSON_TYPE).post(JSONObject.class);
					    fineACI = System.currentTimeMillis();//per calcolo ts
					    
					    int esito_operazione = (int)resp.getLong("esito_operazione");					
						
						//se è stata effettuata la visura
						if(esito_operazione == HttpServletResponse.SC_OK){
							
							String esito_visura = resp.getString("esito_visura");
							String denominazione = resp.getString("denominazione");
							String comune_nascita = resp.getString("comune_nascita");
							String provincia_nascita = resp.getString("provincia_nascita");
							String data_nascita = resp.getString("data_nascita");
							String residenza = resp.getString("residenza"); 
							String provincia_residenza = resp.getString("provincia_residenza"); 
							jsonToReturn.put("esito_operazione", HttpServletResponse.SC_OK);
							jsonToReturn.put("codice_errore","");
							jsonToReturn.put("info","");
							jsonToReturn.put("esito_visura",esito_visura);
							jsonToReturn.put("denominazione",denominazione);
							jsonToReturn.put("comune_nascita",comune_nascita);
							jsonToReturn.put("provincia_nascita",provincia_nascita);
							jsonToReturn.put("data_nascita",data_nascita);
							jsonToReturn.put("residenza",residenza);
							jsonToReturn.put("provincia_residenza",provincia_residenza);
							
							//
							 //codice per il calcolo tempo esecuzione
							 //
							fine = System.currentTimeMillis();
							long tsACI = fineACI - inizioACI;
							long tsBE = fineDB - inizioDB;
							long tsFE = fine - inizio - tsBE - tsACI;
							
							jsonToReturn.put("tsFE",tsFE);
							jsonToReturn.put("tsBE",tsBE);
							jsonToReturn.put("tsACI",tsACI);
							
							logger.info("Ottenuta risposta alla visura da ACIPRARest");
						}
						else{
							try{
						      	jsonToReturn.put("codice_errore",Costanti.ACI_PRA_ERROR);
						      	jsonToReturn.put("info","Errore: non e' stato possibile interrogare ACI PRA");
							}catch(JSONException je){}
						}
	
				      	
				    }catch(Exception e){
						try{
					      	jsonToReturn.put("codice_errore",Costanti.ACI_PRA_ERROR);
					      	jsonToReturn.put("info","Errore: non e' stato possibile interrogare ACI PRA");
						}catch(JSONException je){}
				    	logger.error("errore nella comunicazione con ACIPRARest: "+e.getMessage());
					}
	
				}
			}

			return jsonToReturn;

		}
		

}